﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using KMF.Common;
using KMF.DAL;
using KMF.WebUI.Areas.KMFadmin.CustomHelpers;
using KMF.WebUI.Areas.KMFadmin.Infrastructure;
using KMF.WebUI.Areas.KMFadmin.Models;
using KMF.WebUI.Areas.KMFadmin.Attributes;

namespace KMF.WebUI.Areas.KMFadmin.Controllers
{
    [AdminLoggedAuthorize]
    public class AdminProductController : Controller
    {
        //
        // GET: /Admin/Product/

        public ActionResult Index(int page = 1)
        {
            var totalPage = 0;
            var itemsPerPage = int.Parse(ConfigurationManager.AppSettings["DefaultItemsPerPage"]);
            ViewBag.Page = page;
            var model = ProductDb.GetAllProductPaging(page, itemsPerPage, ref totalPage) ?? new List<ProductListForPagingDto>();
            ViewBag.PageInfo = new PageInfo { CurrentPage = page, PageSize = itemsPerPage, TotalPages = totalPage };
            ViewBag.MenuList = FunctionHelper.GetMenuListThreeLevel() ?? new List<ProductCategoryDto>();

            return View(model);
        }
       


        #region Khuyến mại

        public JsonResult UpdateDiscountInfo(int discountId, string productId)
        {
            DiscountDb.DeleteDiscountApplyProduct(productId);
            var result = DiscountApplyToProductDb.Add(new DiscountApplyToProductDto { DiscountId = discountId, ProductId = productId });
            return Json(result > 0, JsonRequestBehavior.AllowGet);
        }

        public JsonResult UpdateGiftInfo(int giftId, string productId)
        {
            GiftDb.DeleteGiftApplyToProduct(productId);
            var result = GiftApplyToProductDb.Add(new GiftApplyToProductDto { GiftId = giftId, ProductId = productId });
            return Json(result > 0, JsonRequestBehavior.AllowGet);
        }

        public JsonResult DeleteDiscountApplyProduct(int discountId, string productId)
        {
            var result = DiscountApplyToProductDb.Delete(discountId, productId);
            var model = new { Data = result > 0, DiscountId = discountId };
            return Json(model, JsonRequestBehavior.AllowGet);
        }

        public JsonResult DeleteGiftApplyProduct(int giftId, string productId)
        {
            var result = GiftApplyToProductDb.Delete(giftId, productId);
            var model = new { Data = result > 0, GiftId = giftId };
            return Json(model, JsonRequestBehavior.AllowGet);
        }

        #endregion

        public ActionResult ProductByCate(int page = 1, string categoryId = "")
        {
            var totalPage = 0;
            var itemsPerPage = int.Parse(ConfigurationManager.AppSettings["DefaultItemsPerPage"]);
            ViewBag.Page = page;
            var model = ProductDb.GetAllProductByCategoryId(page, itemsPerPage, ref totalPage, categoryId) ?? new List<ProductRateByCateTopListPagingDto>();
            ViewBag.PageInfo = new PageInfo { CurrentPage = page, PageSize = itemsPerPage, TotalPages = totalPage };
            ViewBag.MenuList = FunctionHelper.GetMenuListThreeLevel() ?? new List<ProductCategoryDto>();
            ViewBag.CateId = categoryId;
            return View(model);
        }

        public ActionResult Add()
        {
            ViewBag.MenuList = FunctionHelper.GetMenuListThreeLevel();

            var providerList = ProviderDb.GetAll() ?? new List<ProviderDto>();
            if (providerList.Any())
            {
                providerList = providerList.OrderBy(m => m.Name).ToList();
            }

            providerList.Insert(0, new ProviderDto { Name = "--" });
            ViewBag.ProviderList = providerList;

            ViewBag.ProductStatusList = CommonHelpers.GetProductStatusList();

            // Discount
            ViewBag.DiscountList = DiscountDb.GetDiscountApplyProduct() ?? new List<DiscountDto>();
            ViewBag.GiftList = GiftDb.GetGiftApplyProduct() ?? new List<GiftDto>();
            return View();
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Add(ProductDto model, string productTags, HttpPostedFileBase imageFile, int discountId = 0, int giftId = 0)
        {
            string imagePath = string.Empty;
            if (imageFile != null)
            {
                string error;
                imagePath = ImageHelper.UploadProductImage(out error, imageFile);
                if (!string.IsNullOrEmpty(error))
                {
                    ModelState.AddModelError("ErrorSummary", error);
                    ViewBag.MenuList = FunctionHelper.GetMenuListThreeLevel();

                    var providerList = ProviderDb.GetAll() ?? new List<ProviderDto>();
                    providerList.Insert(0, new ProviderDto { Name = "--" });
                    ViewBag.ProviderList = providerList;

                    ViewBag.ProductStatusList = CommonHelpers.GetProductStatusList();
                    return View(model);
                }
            }

            model.Id = FunctionHelper.GenerateId();
            model.Price = model.Price < 0 ? 0 : model.Price;
            model.CreateDate = DateTime.Now;
            model.Quantity = 1;
            model.ImagePath = imagePath;

            if (ProductDb.Add(model) > 0)
            {
                if (discountId > 0) DiscountApplyToProductDb.Add(new DiscountApplyToProductDto { DiscountId = discountId, ProductId = model.Id });
                if (giftId > 0) GiftApplyToProductDb.Add(new GiftApplyToProductDto { GiftId = giftId, ProductId = model.Id });

                // Insert product tag
                if (!string.IsNullOrEmpty(productTags))
                {
                    ProductTagDb.AddProductTag(model.Id, productTags.TrimSpaceFistLastEachCharacter());
                }
                return RedirectToAction("Index", "AdminProduct");
            }

            return View(model);
        }

        public ActionResult Edit(string id)
        {
            var model = ProductDb.GetById(id);
            ViewBag.MenuList = FunctionHelper.GetMenuListThreeLevel();

            // Provider List
            var providerList = ProviderDb.GetAll() ?? new List<ProviderDto>();
            providerList.Insert(0, new ProviderDto { Name = "--" });
            if (providerList.Any())
            {
                providerList = providerList.OrderBy(m => m.Name).ToList();
            }
            ViewBag.ProviderList = providerList;

            ViewBag.ProductStatusList = CommonHelpers.GetProductStatusList();

            ViewBag.ColorList = ColorDb.GetAll() ?? new List<ColorDto>();
            ViewBag.ProductSizeList = ProductSizeDb.GetAllByProductId(id) ?? new List<ProductSizeListByPidDto>();
            ViewBag.SizeList = SizeDb.GetAll() ?? new List<SizeDto>();

            ViewBag.ProductImageList = ProductImageDb.GetImagesByProductId(id) ?? new List<ProductImageHasColorNameDto>();

            // Discount
            ViewBag.DiscountList = DiscountDb.GetDiscountApplyProduct() ?? new List<DiscountDto>();
            ViewBag.GiftList = GiftDb.GetGiftApplyProduct() ?? new List<GiftDto>();
            ViewBag.GiftId = GiftDb.GetGiftIdByProductId(id);
            ViewBag.DiscountId = DiscountDb.GetDiscountIdByProductId(id);

            // Product Tags
            var productTagModel = ProductTagDb.GetProductTagByProductId(id) ?? new List<ProductTagDto>();
            var productTagList = "";
            if (productTagModel.Any())
            {
                productTagList = productTagModel.Aggregate(productTagList, (current, productTagDto) => current + (productTagDto.Name + ","));
            }
            ViewBag.ProductTag = productTagList;

            // Product comment
            ViewBag.ProductComment = ProductCommentDb.GetProductCommentByProductId(id) ?? new List<ProductCommentDto>();

            return View(model);
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Edit(ProductDto model, string productTags, HttpPostedFileBase imageFile)
        {
            string imagePath = string.Empty;
            if (imageFile != null)
            {
                string error;
                imagePath = ImageHelper.UploadProductImage(out error, imageFile, model.ImagePath);
                if (!string.IsNullOrEmpty(error))
                {
                    ModelState.AddModelError("ErrorSummary", error);
                    ViewBag.MenuList = FunctionHelper.GetMenuListThreeLevel();

                    var productProviderList = ProviderDb.GetAll() ?? new List<ProviderDto>();
                    productProviderList.Insert(0, new ProviderDto { Name = "--" });
                    ViewBag.ProviderList = productProviderList;

                    ViewBag.ProductStatusList = CommonHelpers.GetProductStatusList();

                    ViewBag.ColorList = ColorDb.GetAll() ?? new List<ColorDto>();
                    ViewBag.ProductSizeList = ProductSizeDb.GetAllByProductId(model.Id) ?? new List<ProductSizeListByPidDto>();
                    ViewBag.SizeList = SizeDb.GetAll() ?? new List<SizeDto>();

                    ViewBag.ProductImageList = ProductImageDb.GetImagesByProductId(model.Id) ?? new List<ProductImageHasColorNameDto>();

                    // Discount
                    ViewBag.DiscountList = DiscountDb.GetDiscountApplyProduct() ?? new List<DiscountDto>();
                    ViewBag.GiftList = GiftDb.GetGiftApplyProduct() ?? new List<GiftDto>();
                    ViewBag.GiftId = GiftDb.GetGiftIdByProductId(model.Id);
                    ViewBag.DiscountId = DiscountDb.GetDiscountIdByProductId(model.Id);

                    // Product Tags
                    ViewBag.ProductTag = productTags;
                    // Product comment
                    ViewBag.ProductComment = ProductCommentDb.GetProductCommentByProductId(model.Id) ?? new List<ProductCommentDto>();
                    return View(model);
                }
            }

            model.Price = model.Price < 0 ? 0 : model.Price;
            model.ImagePath = string.IsNullOrEmpty(imagePath) ? model.ImagePath : imagePath;
            ProductDb.Update(model);

            // Update Product Tags
            ProductTagDb.DeleteProductTagMappingByProductId(model.Id);
            ProductTagDb.UpdateProductTag(model.Id, productTags);

            ViewBag.MenuList = FunctionHelper.GetMenuListThreeLevel();
            var providerList = ProviderDb.GetAll() ?? new List<ProviderDto>();
            providerList.Insert(0, new ProviderDto { Name = "--" });
            ViewBag.ProviderList = providerList;

            ViewBag.ProductStatusList = CommonHelpers.GetProductStatusList();

            ViewBag.ColorList = ColorDb.GetAll() ?? new List<ColorDto>();
            ViewBag.ProductSizeList = ProductSizeDb.GetAllByProductId(model.Id) ?? new List<ProductSizeListByPidDto>();
            ViewBag.SizeList = SizeDb.GetAll() ?? new List<SizeDto>();

            ViewBag.ProductImageList = ProductImageDb.GetImagesByProductId(model.Id) ?? new List<ProductImageHasColorNameDto>();

            // Discount
            ViewBag.DiscountList = DiscountDb.GetDiscountApplyProduct() ?? new List<DiscountDto>();
            ViewBag.GiftList = GiftDb.GetGiftApplyProduct() ?? new List<GiftDto>();
            ViewBag.GiftId = GiftDb.GetGiftIdByProductId(model.Id);
            ViewBag.DiscountId = DiscountDb.GetDiscountIdByProductId(model.Id);

            // Product Tags
            ViewBag.ProductTag = productTags;
            return RedirectToAction("Index", "AdminProduct");
        }

        public ActionResult ManagerImages()
        {
            return PartialView();
        }

        [HttpPost]
        public WrappedJsonResult UploadImage(ProductImageDto model, HttpPostedFileWrapper imageFile)
        {
            if (imageFile == null || imageFile.ContentLength == 0)
            {
                return new WrappedJsonResult
                {
                    Data = new { IsValid = false, Message = "No file was uploaded." }
                };
            }
            string error;

            // Get current date
            var subFolder = DateTime.Now.Day.ToString("00") + "\\" + DateTime.Now.Month.ToString("00") + "\\" + DateTime.Now.Year.ToString();
            var currentDate = DateTime.Now.ToString("dd/MM/yyyy");

            // Create sub folder by datetime
            var fullFolder = Path.Combine(Server.MapPath(ConstVariableList.FolderUploadImageRoot), subFolder);
            if (!Directory.Exists(fullFolder))
                Directory.CreateDirectory(fullFolder);

            // Create root images
            var fileName = FunctionHelper.UploadImages(out error, fullFolder, imageFile);

            // Create thumbnail folder and save images
            //FunctionHelpers.CreateProductThumbnail(fullFolder, fileName, ConfigurationManager.AppSettings["ProductTemplateForThumbnail"], imageFile);

            // Insert or update infomation into productImage table
            if (!string.IsNullOrEmpty(model.Id))
            {
                model.ImageName = fileName;
                model.ImagePath = Url.Content(string.Format("~/upload/images/{0}", currentDate));
                model.CreatedDate = DateTime.Now;
                var result = ProductImageDb.Update(model);
                if (result > 0)
                {
                    var dataItem = ProductImageDb.GetImagesById(model.Id);
                    var data = new
                    {
                        UpdateStatus = "1",
                        ImagePath = dataItem.ImagePath,
                        ImageName = dataItem.ImageName,
                        ColorName = dataItem.ColorName,
                        Avartar = dataItem.Avartar,
                        Active = dataItem.Active,
                        Id = dataItem.Id,
                        ProductId = dataItem.ProductId,
                        Code = dataItem.Code,
                        ColorId = dataItem.ColorId
                    };
                    return new WrappedJsonResult { Data = data };
                }
            }
            else
            {
                model.Id = FunctionHelper.GenerateId();
                model.ImageName = fileName;
                model.ImagePath = Url.Content(string.Format("~/upload/images/{0}", currentDate));
                model.CreatedDate = DateTime.Now;
                var result = ProductImageDb.Add(model);
                if (result > 0)
                {
                    var data = ProductImageDb.GetImagesById(model.Id);
                    return new WrappedJsonResult { Data = data };
                }
            }

            return new WrappedJsonResult
            {
                Data = new { IsValid = false, Message = "Đã có lỗi xảy ra." }
            };
        }

        public ActionResult CreateFolder(string realFolder)
        {
            var physical = Server.MapPath(realFolder);
            Directory.CreateDirectory(physical);
            return Json(true, JsonRequestBehavior.AllowGet);
        }

        public JsonResult ChangeProductImage(string id)
        {
            var model = ProductImageDb.GetById(id);
            return Json(model, JsonRequestBehavior.AllowGet);
        }

        public JsonResult SetAvartar(string id, string productId)
        {
            var model = new ProductImageDto { Id = id, ProductId = productId };
            if (ProductImageDb.UpdateAvartarStatus(model) > 0)
                return Json(true, JsonRequestBehavior.AllowGet);
            return Json(false, JsonRequestBehavior.AllowGet);
        }

        public JsonResult DeleteProduct(string id)
        {
            // Delete images of product
            var deleteStatus = true;
            var pImageList = ProductImageDb.GetAllByProductId(id) ?? new List<ProductImageDto>();
            foreach (var item in pImageList)
            {
                deleteStatus = FunctionHelper.DeleteProductImages(item.ImagePath, item.ImageName);
            }
            if (deleteStatus == false)
                return Json(false, JsonRequestBehavior.AllowGet);

            // Delete record of product
            var result = ProductDb.DeleteProduct(id);
            return Json(result > 0, JsonRequestBehavior.AllowGet);
        }

        public JsonResult AddSize(ProductSizeDto model, string code)
        {
            model.CreateDate = DateTime.Now;
            var data = new object();
            try
            {
                ProductSizeDb.Add(model);
                data = new
                {
                    AddStatus = true,
                    Code = code,
                    ProductId = model.ProductId,
                    Show = model.Show,
                    SizeId = model.SizeId,
                    SizePrice = model.SizePrice,
                    CreateDate = model.CreateDate.ToString(),
                    Order = model.Order
                };
            }
            catch
            {
                data = new { AddStatus = false };
            }
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        public JsonResult DeleteProductSize(string sizeId, string productId)
        {
            var result = ProductSizeDb.Delete(sizeId, productId);
            return Json(result > 0, JsonRequestBehavior.AllowGet);
        }

        public JsonResult UpdateProductSize(ProductSizeDto model, string code)
        {
            ProductSizeDb.Update(model);
            var data = new
            {
                Code = code,
                SizePrice = model.SizePrice,
                Show = model.Show,
                SizeId = model.SizeId,
                ProductId = model.ProductId,
                CreateDate = model.CreateDate.ToString(),
                Order = model.Order
            };
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        public ActionResult TypicalAttribute(string productId)
        {
            var model = ProductTypicalAttributeDb.GetAllByProductId(productId) ?? new List<ProductTypicalAttributeDto>();
            ViewBag.ProductId = productId;
            return PartialView(model);
        }

        public JsonResult AddTypicalAttribute(ProductTypicalAttributeDto model)
        {
            model.CreatedDate = DateTime.Now;
            model.ModifiedDate = DateTime.Now;
            model.Id = FunctionHelper.GenerateId();
            var result = ProductTypicalAttributeDb.Add(model);
            var data = new
            {
                Id = model.Id,
                Name = model.Name,
                Description = model.Description,
                CreatedDate = model.CreatedDate.ToString("MM/dd/yyyy"),
                Show = model.Show,
                ProductId = model.ProductId,
                Ordering = model.Ordering
            };
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        public JsonResult DeleteProductTypicalAttribute(string id)
        {
            var result = ProductTypicalAttributeDb.Delete(id);
            return Json(result > 0, JsonRequestBehavior.AllowGet);
        }

        public JsonResult EditTypicalAttribute(ProductTypicalAttributeDto model)
        {
            model.ModifiedDate = DateTime.Now;
            var result = ProductTypicalAttributeDb.Update(model);
            var data = new
            {
                Id = model.Id,
                Name = model.Name,
                Description = model.Description,
                CreatedDate = model.CreatedDate.ToString("MM/dd/yyyy"),
                Show = model.Show,
                ProductId = model.ProductId,
                Ordering = model.Ordering
            };
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        public ActionResult SearchProduct(string keyword = "", int page = 1)
        {
            var itemsPerPage = int.Parse(ConfigurationManager.AppSettings["DefaultItemsPerPage"]);
            var totalPage = 0;
            var model = ProductDb.GetAllProductByKeyWordAdmin(page, itemsPerPage, ref totalPage, keyword) ?? new List<ProductListForPagingDto>();
            ViewBag.Keyword = keyword;
            ViewBag.PageInfo = new PageInfo { CurrentPage = page, PageSize = itemsPerPage, TotalPages = totalPage };
            ViewBag.MenuList = FunctionHelper.GetMenuListThreeLevel() ?? new List<ProductCategoryDto>();
            return View(model);
        }

        public ActionResult DeleteImage(string id)
        {
            // Delete images of product
            var deleteStatus = true;
            var delImageStatus = true;
            var pImage = ProductImageDb.GetById(id) ?? new ProductImageDto();
            delImageStatus = FunctionHelper.DeleteProductImages(pImage.ImagePath, pImage.ImageName);
            deleteStatus = ProductImageDb.Delete(id) > 0;
            return Json(deleteStatus != false && delImageStatus != false, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Change price batch from file excel
        /// </summary>
        /// <returns></returns>
        public ActionResult ChangePriceBatch()
        {
            return View();
        }

        [HttpPost]
        public ActionResult ChangePriceBatch(HttpPostedFileBase itemFile)
        {
            var extension = Path.GetExtension(itemFile.FileName);
            return RedirectToAction("ChangePriceBatch");
        }

        public JsonResult ProducCommentUpdate(int pId, bool agree, bool active)
        {
            var data = ProductCommentDb.UpDateActive_ProductComment(pId, agree, active);
            return Json(data, JsonRequestBehavior.AllowGet);
        }
        public JsonResult ProducCommentDel(int pId)
        {
            var data = ProductCommentDb.Delete(pId);
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        public ActionResult ProductTogether(string productId)
        {
            ViewBag.ProductId = productId;
            ViewBag.MenuList = FunctionHelper.GetMenuListThreeLevel() ?? new List<ProductCategoryDto>();
            return PartialView();
        }

        public PartialViewResult AjaxProductByCate(string categoryId)
        {
            var page = 1;
            var totalPage = 0;
            var itemsPerPage = 1000;
            ViewBag.Page = page;
            var model = ProductDb.GetAllProductByCategoryId(page, itemsPerPage, ref totalPage, categoryId) ?? new List<ProductRateByCateTopListPagingDto>();
            return PartialView(model);
        }
        public PartialViewResult GetListProductTogether(string productId)
        {
            var model = ProductTogetherDb.GetProductTogetherByProductId(productId);
            return PartialView(model);
        }

        public JsonResult AddTogether(string ListMap, string ProductId)
        {
            var arr = ListMap.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            if (arr.Length > 0)
            {
                foreach (var mapId in arr)
                {
                    if (mapId == ProductId) continue;
                    ProductTogetherDb.AddProductTogether(ProductId, mapId, true);
                }
            }
            return Json(true, JsonRequestBehavior.AllowGet);
        }
        public JsonResult DelTogether(int togetherId)
        {
            ProductTogetherDb.Delete(togetherId);
            return Json(true, JsonRequestBehavior.AllowGet);
        }
        public JsonResult DelAllTogether(string productId)
        {
            ProductTogetherDb.DelAllTogether(productId);
            return Json(true, JsonRequestBehavior.AllowGet);
        }
    }
}
